﻿
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Jint;

using Newtonsoft.Json;

using FullCoreDBModels;

using RestSharp;
using Microsoft.AspNetCore.Http.Headers;
using RestSharp.Serializers.Xml;
using System.Globalization;
using System.Net.Mail;
using System.Xml.Linq;
using System.Xml;
using static System.Net.Mime.MediaTypeNames;
using System.Buffers;
using System.Runtime.InteropServices;
using System.Text.Unicode;
using System.Text;
using MyApp.IRepository;
using MyApp.Common;
using MyApp.WebApi.DataModels;
using MyApp.DataModels.DTO;
using MyApp.IService;

namespace MyApp.WebApi.Controllers
{

    [ApiController]
    [Route("api/[controller]/[action]")]
    /// <summary>
    /// JavaScript 解释执行器
    /// </summary>
    public class JavaScriptController : ControllerBase
    {
        Jint.Engine engine;
        ISqlService sqlService;
        /// <summary>
        /// JavaScript 解释 构造方法
        /// </summary>
        /// <param name="OracleRespository"></param>
        public JavaScriptController(ISqlService _sqlService)
        {
            engine = new Engine();
            sqlService = _sqlService;
            engine.SetValue("NLog", new Action<object>(NLog));//记录日志
            engine.SetValue("GetDataTable", new Func<int, string, string>(GetDataTable));//查询数据库
            engine.SetValue("ExecuteCommand", new Func<int, string, string>(ExecuteCommand));//执行数据库
            engine.SetValue("RestSharpGet", new Func<string, string, int?, string, string>(RestSharpGet));//GET请求API
            engine.SetValue("RestSharpPost", new Func<string, string, object, int?, string, string>(RestSharpPost));//Post请求API
            engine.SetValue("SoapPost", new Func<string, string, string, string, string, string>(SoapPost));
        }
        #region 注册方法


        private string RestSharpGet(string url, string resource, int? timeout = null, string headers = null)
        {
            try
            {
                var client = new RestClient(url);
                var request = new RestRequest(resource, Method.Get);
                request.Timeout = timeout ?? 5000;
                request.AddParameter("auth", "jhecis", ParameterType.HttpHeader);
                if (!string.IsNullOrEmpty(headers))
                {
                    var listHeader = JsonConvert.DeserializeObject<List<RequestHeader>>(headers);
                    listHeader?.ForEach(a => { request.AddHeader(a.Name, a.Value); });
                }
                var response = client.Execute(request);
                if (response.ErrorException != null)
                {
                    return SerialzeError(response.ErrorMessage);
                }
                return response.Content;
            }
            catch (Exception ex)
            {
                return SerialzeError(ex.Message);
            }
        }
        private string RestSharpPost(string url, string resource, object value, int? timeout = null, string headers = null)
        {
            try
            {
                var client = new RestClient(url);
                var request = new RestRequest(resource, Method.Post);
                request.Timeout = timeout ?? 5000;
                request.AddParameter("auth", "jhecis", ParameterType.HttpHeader);
                if (!string.IsNullOrEmpty(headers))
                {
                    var listHeader = JsonConvert.DeserializeObject<List<RequestHeader>>(headers);
                    listHeader?.ForEach(a => { request.AddHeader(a.Name, a.Value); });
                }
                request.AddJsonBody(value);
                var response = client.Execute(request);
                if (response.ErrorException != null)
                {
                    return SerialzeError(response.ErrorMessage);
                }
                return response.Content;
            }
            catch (Exception ex)
            {
                return SerialzeError(ex.Message);
            }
        }
        private static string ResolveTask(Func<Task<string>> fn) => Task.Run(fn).Result;

        private string SoapPost(string url, string res, string body, string header = null, string action = null)
        {
            try
            {
                var client = new RestClient();
                var request = new RestRequest(url, Method.Post);
                request.Timeout = -1;
                if (header == null)
                    request.AddHeader("Content-Type", "text/xml;charset=utf-8");
                else
                    request.AddHeader("Content-Type", header);

                if (action != null)
                    request.AddHeader("SOAPAction", action);
                byte[] bodyxml = Encoding.UTF8.GetBytes(body);
                request.AddParameter("text/xml;", bodyxml, ParameterType.RequestBody);
                RestResponse response = client.Execute(request);
                if (response != null)
                    return response.Content;
                else
                    return "接口未获取到信息";



            }
            catch (Exception ex)
            {
                return SerialzeError(ex.Message);
            }
        }


        /// <summary>
        /// 添加日志
        /// </summary>
        /// <param name="msg"></param>
        private void NLog(object msg)
        {
            //LogerHelper.GetLog().Info(msg.ToString());
        }

       /// <summary>
       /// 查询数据
       /// </summary>
       /// <param name="configId"></param>
       /// <param name="sql"></param>
       /// <returns></returns>
        private string GetDataTable(int configId, string sql)
        {
            try
            {
                var data = sqlService.GetDataTable(configId, sql);
                return JsonConvert.SerializeObject(data);
            }
            catch (Exception e)
            {
                return SerialzeError(e.Message);
            }

        }

       /// <summary>
       /// 执行命令
       /// </summary>
       /// <param name="configId"></param>
       /// <param name="sql"></param>
       /// <returns></returns>
        private string ExecuteCommand(int configId, string sql)
        {
            try
            {
                var data = sqlService.ExecuteCommand(configId, sql);
                return JsonConvert.SerializeObject(data);
            }
            catch (Exception e)
            {
                return SerialzeError(e.Message);
            }

        }
        private string SerialzeError(string errmsg)
        {
            var result = new CommonResult() { Result = false, ErrMsg = errmsg };
            return JsonConvert.SerializeObject(result);
        }

        #endregion

        /// <summary>
        /// Post 转换数据
        /// </summary>
        /// <param name="script"></param>
        /// <returns></returns>
        [HttpPost]

        public string Convert([FromBody] ScriptContent script)
        {
            try
            {
                engine.Execute(script.JavaScriptCode);
                var result = engine.Invoke(script.FunctionName, script.Data);
                return result.AsString();
            }
            catch (Exception ex)
            {
                // LogerHelper.GetLog().Error(ex.Message);
                throw new Exception($"转换错误【{ex.Message}】", ex);
            }
        }
    }
    class RequestHeader
    {
        public string Name { get; set; }
        public string Value { get; set; }
    }
}
